<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AI对话助手</title>
    <script src="./style.js"></script>
    <style>
      /* 自定义滚动条样式 */
      .custom-scrollbar::-webkit-scrollbar {
        width: 6px;
      }
      .custom-scrollbar::-webkit-scrollbar-track {
        background: #f1f1f1;
      }
      .custom-scrollbar::-webkit-scrollbar-thumb {
        background: #c1c1c1;
        border-radius: 3px;
      }
      .custom-scrollbar::-webkit-scrollbar-thumb:hover {
        background: #a8a8a8;
      }
      think {
        color: #a8a8a8;
        font-size: 0.8rem;
      }
      /* 打字动画 */
      @keyframes typing {
        from {
          width: 0;
        }
        to {
          width: 100%;
        }
      }
      .typing-indicator::after {
        content: "|";
        animation: blink 1s step-end infinite;
      }
      @keyframes blink {
        from,
        to {
          opacity: 1;
        }
        50% {
          opacity: 0;
        }
      }
    </style>
  </head>
  <body class="bg-gray-50 min-h-screen flex flex-col">
    <!-- 顶部标题栏 -->
    <header class="bg-blue-600 text-white p-4 shadow-md">
      <div class="container mx-auto flex justify-between items-center">
        <h1 class="text-xl font-bold">AI智能助手</h1>
        <div class="text-sm opacity-80">基于流式响应的智能对话</div>
      </div>
    </header>

    <!-- 主聊天区域 -->
    <main
      class="flex-1 container mx-auto p-4 overflow-hidden flex flex-col"
      style="max-height: calc(100vh - 60px)"
    >
      <!-- 消息列表容器 -->
      <div
        id="message-container"
        class="flex-1 overflow-y-auto custom-scrollbar mb-4 space-y-4"
      >
        <!-- 初始欢迎消息 -->
        <div class="flex items-start">
          <div class="flex-shrink-0 mr-3">
            <div
              class="w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center text-white font-bold"
            >
              AI
            </div>
          </div>
          <div class="bg-gray-100 rounded-lg p-3 max-w-[80%]">
            <div class="text-sm text-gray-500 mb-1">AI助手</div>
            <div>您好！我是AI助手，请先输入提示词和问题，然后点击发送。</div>
          </div>
        </div>
      </div>

      <!-- 输入区域 -->
      <div
        class="bg-white rounded-lg shadow-md p-4 border border-gray-200 space-y-4"
      >
        <!-- 提示词输入区域 -->
        <div>
          <label
            for="prompt-input"
            class="block text-sm font-medium text-gray-700 mb-1"
            >提示词输入</label
          >
          <input
            id="prompt-input"
            type="text"
            class="w-full border border-gray-300 rounded-lg p-3 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none"
            placeholder="输入提示词(如:城镇)..."
          />
        </div>

        <!-- 问题输入区域 -->
        <div>
          <label
            for="message-input"
            class="block text-sm font-medium text-gray-700 mb-1"
            >问题输入</label
          >
          <textarea
            id="message-input"
            rows="3"
            class="w-full border border-gray-300 rounded-lg p-3 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none resize-none"
            placeholder="输入您的问题..."
          ></textarea>
        </div>

        <!-- 状态和控制按钮 -->
        <div class="flex justify-between items-center">
          <div id="status-indicator" class="text-sm text-gray-500">
            准备就绪
          </div>
          <div class="flex space-x-2">
            <button
              id="stop-button"
              class="hidden bg-red-100 text-red-600 px-3 py-1 rounded text-sm hover:bg-red-200 disabled:opacity-50"
              disabled
            >
              停止生成
            </button>
            <button
              id="send-button"
              class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
              disabled
            >
              发送
            </button>
          </div>
        </div>
      </div>
    </main>

    <script>
      // 全局变量
      let currentAiMessageId = null;
      let isStreaming = false;
      let abortController = null;

      // DOM元素
      const messageContainer = document.getElementById("message-container");
      const promptInput = document.getElementById("prompt-input");
      const messageInput = document.getElementById("message-input");
      const sendButton = document.getElementById("send-button");
      const stopButton = document.getElementById("stop-button");
      const statusIndicator = document.getElementById("status-indicator");

      // 初始化事件监听
      document.addEventListener("DOMContentLoaded", () => {
        // 输入框变化时启用/禁用发送按钮
        const checkInputs = () => {
          sendButton.disabled =
            promptInput.value.trim() === "" || messageInput.value.trim() === "";
        };

        promptInput.addEventListener("input", checkInputs);
        messageInput.addEventListener("input", checkInputs);

        // 按Enter键发送消息，Shift+Enter换行
        messageInput.addEventListener("keydown", (e) => {
          if (e.key === "Enter" && !e.shiftKey) {
            e.preventDefault();
            if (!sendButton.disabled) {
              sendMessage();
            }
          }
        });

        // 发送按钮点击事件
        sendButton.addEventListener("click", sendMessage);

        // 停止按钮点击事件
        stopButton.addEventListener("click", stopGeneration);
      });

      /**
       * 发送用户消息并获取AI响应
       */
      async function sendMessage() {
        const prompt = promptInput.value.trim();
        const message = messageInput.value.trim();
        if (!prompt || !message) return;

        // 如果之前有正在进行的对话，先停止它
        if (isStreaming) {
          stopGeneration(); // 中止上一次的对话
        }

        // 添加用户消息到界面
        addMessage(`[提示词: ${prompt}] ${message}`, true);
        messageInput.value = "";
        sendButton.disabled = true;

        // 显示加载状态
        statusIndicator.textContent = "AI正在思考...";
        stopButton.classList.remove("hidden");
        stopButton.disabled = false;
        isStreaming = true;

        // 创建新的AbortController用于中断请求
        abortController = new AbortController();

        try {
          const response = await fetch(
            "https://15808108713.hsk.top/task/ChatHandler",
            {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
                Accept: "text/event-stream",
              },
              body: JSON.stringify({
                tword: prompt, // 使用输入的提示词
                mword: message,
              }),
              signal: abortController.signal,
            }
          );

          if (!response.ok) {
            throw new Error(`HTTP错误! 状态码: ${response.status}`);
          }

          const reader = response.body.getReader();
          const decoder = new TextDecoder();
          let fullResponse = "";

          while (true) {
            const { done, value } = await reader.read();
            if (done) {
              removeTypingIndicator();
              isStreaming = false;
              stopButton.disabled = true;
              statusIndicator.textContent = "准备就绪";
              break;
            }

            const chunk = decoder.decode(value, { stream: true });
            const lines = chunk.split("\n");

            for (const line of lines) {
              if (line.startsWith("data:")) {
                const data = line.substring(5).trim();
                if (!currentAiMessageId) {
                  currentAiMessageId = addMessage("", false, true); // 创建AI消息并添加打字指示器
                }
                fullResponse += data;
                updateMessage(currentAiMessageId, fullResponse);
              }
            }
          }
        } catch (error) {
          if (error.name === "AbortError") {
            updateMessage(currentAiMessageId, "(已停止生成)");
            statusIndicator.textContent = "已停止";
          } else {
            console.error("错误:", error);
            addMessage("抱歉，发生了一些错误。请稍后再试。", false);
            statusIndicator.textContent = "错误: " + error.message;
          }
          removeTypingIndicator();
          isStreaming = false;
          stopButton.disabled = true;
        }
      }

      /**
       * 停止AI生成
       */
      function stopGeneration() {
        if (isStreaming && abortController) {
          abortController.abort();
        }
      }

      /**
       * 添加新消息到聊天界面
       * @param {string} content 消息内容
       * @param {boolean} isUser 是否是用户消息
       * @param {boolean} showTyping 是否显示打字指示器
       * @returns {string} 消息元素的ID
       */
      function addMessage(content, isUser, showTyping = false) {
        const messageId = "msg-" + Date.now();
        const messageClass = isUser ? "justify-end" : "justify-start";
        const bubbleClass = isUser ? "bg-blue-100" : "bg-gray-100";
        const avatarText = isUser ? "用户" : "AI";
        const avatarColor = isUser ? "bg-green-500" : "bg-blue-500";

        const typingIndicator = showTyping ? "typing-indicator" : "";

        const messageHTML = `
    <div id="${messageId}" class="flex ${messageClass}">
      ${
        !isUser
          ? `
        <div class="flex-shrink-0 mr-3">
          <div class="w-8 h-8 rounded-full ${avatarColor} flex items-center justify-center text-white font-bold">${avatarText}</div>
        </div>`
          : ""
      }
      <div class="${bubbleClass} rounded-lg p-3 max-w-[80%]">
        <div class="text-sm text-gray-500 mb-1">${
          isUser ? "用户" : "AI助手"
        }</div>
        <div class="${typingIndicator}" id="message-content-${messageId}">${content}</div>
      </div>
      ${
        isUser
          ? `
        <div class="flex-shrink-0 ml-3">
          <div class="w-8 h-8 rounded-full ${avatarColor} flex items-center justify-center text-white font-bold">${avatarText}</div>
        </div>`
          : ""
      }
    </div>
  `;

        messageContainer.insertAdjacentHTML("beforeend", messageHTML);
        scrollToBottom();
        return messageId;
      }

      /**
       * 更新已有消息的内容
       * @param {string} messageId 消息ID
       * @param {string} newContent 新内容
       */
      function updateMessage(messageId, newContent) {
        console.log("newContent :>> ", newContent);
        if (newContent.endsWith("completed")) {
          console.log("已生成完毕 :>> ");
          return;
        }
        const messageElement = document.getElementById(
          `message-content-${messageId}`
        );
        if (messageElement) {
          messageElement.innerHTML = newContent; // 使用 innerHTML 更新内容
          scrollToBottom();
        }
      }

      /**
       * 移除打字指示器
       */
      function removeTypingIndicator() {
        if (currentAiMessageId) {
          const messageElement = document.getElementById(currentAiMessageId);
          if (messageElement) {
            const contentElement = messageElement.querySelector(
              "div > div:last-child"
            );
            if (contentElement) {
              contentElement.classList.remove("typing-indicator");
            }
          }
        }
        currentAiMessageId = null;
      }

      /**
       * 滚动到消息容器底部
       */
      function scrollToBottom() {
        console.log("滚动到底部 :>> ");
        messageContainer.scrollTop = messageContainer.scrollHeight;
      }
    </script>
  </body>
</html>
